package com.cybertron.ironhide.manage.common.jms.listener;

import java.io.IOException;
import java.util.Date;

import javax.annotation.Resource;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.springframework.stereotype.Component;

import com.cybertron.ironhide.manage.common.json.JacksonObjectMapper;
import com.cybertron.ironhide.manage.domain.Product;
import com.cybertron.ironhide.manage.service.ProductService;
import com.cybertron.ironhide.manage.util.CommonUtil;
import com.cybertron.ironhide.manage.util.FileUtil;
import com.cybertron.ironhide.manage.util.SimilarityUtil;
import com.cybertron.ironhide.manage.util.SolrUtil;

@Component
public class ProductMessageListener implements MessageListener {

	private final static Logger logger = Logger
			.getLogger(ProductMessageListener.class);

	@Resource
	private JacksonObjectMapper jacksonObjectMapper;

	@Resource
	private ProductService productService;

	@Resource
	private SolrServer solrServer;

	@Override
	public void onMessage(Message message) {
		TextMessage msg = (TextMessage) message;
		try {
			logger.info("receive msg.....");
			Product product = jacksonObjectMapper.readValue(msg.getText(),
					Product.class);
			savdProduct(product);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}

	private boolean testSimilarityProduct(Product product) {
		SolrQuery query = new SolrQuery();
		query.setQuery(SolrUtil.transformSolrMetacharactor(product.getTitle()));
		query.setRows(1);
		QueryResponse response = null;

		try {
			response = solrServer.query(query);
		} catch (SolrServerException e) {
			e.printStackTrace();
		}
		if (response == null) {
			return true;
		}
		SolrDocumentList docs = response.getResults();
		if (docs == null || docs.size() == 0) {
			return true;
		}
		SolrDocument doc = docs.get(0);
		Double rate = SimilarityUtil.sim(doc.get("title").toString(),
				product.getTitle());
		if (rate > 0.9) {
			if (StringUtils.equals(product.getId(), doc.get("id").toString())) {
				return true;
			} else if (StringUtils.equals(product.getSource(), doc
					.get("source").toString())) {
				return false;
			} else {
				product.setGroupId(doc.get("id").toString());
				return true;
			}
		}
		if (rate > 0.8) {
			if (!StringUtils.equals(product.getSource(), doc.get("source")
					.toString())) {
				product.setGroupId(doc.get("id").toString());
			}
			return true;
		}
		return true;
	}

	private void savdProduct(Product product) {
		if (product == null) {
			return;
		}
		Product persistProduct = productService.selectByTargetUrl(product
				.getTargetUrl());
		if (persistProduct == null) {
			persistProduct = new Product();
		}
		persistProduct.setCategoryId(product.getCategoryId());
		persistProduct.setSeedId(product.getSeedId());
		persistProduct.setTargetUrl(product.getTargetUrl());
		persistProduct.setSourceUrl(product.getSourceUrl());
		persistProduct.setTitle(product.getTitle());
		persistProduct.setKeywords(product.getKeywords());
		persistProduct.setDescription(product.getDescription());
		persistProduct.setImage(FileUtil.saveFile(product.getImage(),
				product.getSource()));
		persistProduct.setPrice(product.getPrice());
		persistProduct.setListPrice(product.getListPrice());
		persistProduct.setSource(product.getSource());
		persistProduct.setFreeShipping(product.getFreeShipping());
		persistProduct.setSummary(product.getSummary());
		if (persistProduct.getPrice() != null
				&& product.getPrice() != persistProduct.getPrice()) {
			persistProduct.setListPrice(persistProduct.getPrice());
		}
		persistProduct.setCreateDate(new Date());
		persistProduct.setModifyDate(new Date());
		Boolean isValid = testSimilarityProduct(persistProduct);
		if (isValid) {
			if (persistProduct.getGroupId() != null) {
				Product parentProduct = productService
						.selectByPrimaryKey(persistProduct.getGroupId());
				if (parentProduct != null) {
					Double[] prices = { parentProduct.getLowestPrice(),
							parentProduct.getHighestPrice(),
							parentProduct.getPrice(), product.getPrice() };
					Double lowestPrice = null;
					Double highestPrice = null;
					for (Double i : prices) {
						if (i == null) {
							continue;
						}
						highestPrice = (highestPrice != null && highestPrice > i) ? highestPrice
								: i;
						lowestPrice = (lowestPrice != null && lowestPrice < i) ? lowestPrice
								: i;
					}
					parentProduct.setHighestPrice(highestPrice);
					parentProduct.setLowestPrice(lowestPrice);
					productService.updateByPrimaryKeySelective(parentProduct);
				}
			}
			if (persistProduct.getId() != null) {
				productService.updateByPrimaryKeySelective(persistProduct);
				logger.info("updated url " + product.getTargetUrl());
			} else {
				persistProduct.setId(CommonUtil.getUUID());
				persistProduct.setCreateDate(new Date());
				productService.insertSelective(persistProduct);
				logger.info("saved url " + product.getTargetUrl());
			}
		}
	}
}
